package com.kt.thread.demo;

import java.util.ArrayList;
import java.util.List;
import java.util.Random;
import java.util.UUID;
import java.util.concurrent.locks.Condition;
import java.util.concurrent.locks.ReentrantLock;

/**
 * Created by tangwy on 2016/3/26.
 */
public class WaitAndNotifyTest {
    public static void test() {
        Product product = new Product();
        Creator creator = new Creator(product);
        Consumer consumer = new Consumer(product);
        //两个线程生产
        new Thread(creator).start();
        new Thread(creator).start();
        //一个线程消费
        new Thread(consumer).start();
    }


    static class Product {
        //产品的最大个数
        private static final int MAX = 10;
        private final ReentrantLock lock = new ReentrantLock();
        private final Condition condition = lock.newCondition();
        private List<String> products = new ArrayList<String>(MAX);

        /**
         * 生产产品
         */
        public synchronized void set() throws InterruptedException {
            while (products.size() == MAX) {
                System.out.println("产品达到最大数，等待消费");
                this.wait();
            }
            String s = "产品" + UUID.randomUUID().toString();
            System.out.println("生产:" + s);
            products.add(s);
            this.notify();
        }

        public synchronized String get() throws InterruptedException {
            while (products.isEmpty()) {
                System.out.println("没有产品啦，等待生产");
                this.wait();
            }
            int i = new Random().nextInt(products.size());
            //System.out.println(i);
            String s = products.get(i);
            products.remove(i);
            this.notifyAll();
            return s;
        }
    }

    /**
     * 生产者
     */
    static  class Creator implements Runnable {
        private Product product;

        public Creator(Product product) {
            this.product = product;
        }

        @Override
        public void run() {
            while (true) {
                try {
                    product.set();
                    Thread.sleep(1200);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
        }
    }


    /**
     * 消费者
     */
    static class Consumer implements Runnable {
        private Product product;

        public Consumer(Product product) {
            this.product = product;
        }

        @Override
        public void run() {
            while (true) {
                try {
                    System.out.println("消费：" + product.get());
                    Thread.sleep(1100);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
        }
    }
}

